﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections.ObjectModel;
using myTwitter.BO;
using myTwitter.API;
using System.Windows.Threading;
using System.ComponentModel;
using myBoard.Framework;
using System.Windows.Data;
using myTwitter.Sorting;
using System.Threading;
using myBoard.Framework.Controls.Navigation;

namespace myTwitter.Model
{
    public class Twitter : INotifyPropertyChanged
    {
        private Tweets _friendsStatus;
        private Tweets _directMessages;        
        private Tweets _allReceivedMessages;
        private Tweets _mentions;
        private Tweets _lastSearchResults;
        private Trends _trends;
        private User _connectedUserInfo;
        private User _selectedUserInfo;
        private bool _synchedWithTwitterProvider;
        

        public User SelectedUserInfo
        {
            get { return _selectedUserInfo; }
            set 
            {
                _selectedUserInfo = value;
                RaisePropertyChanged("SelectedUserInfo");
            }
        }

        public User ConnectedUserInfo
        {
            get { return _connectedUserInfo; }
        }

        public ObservableCollection<IMessage> LastSearchResults
        {
            get { return _lastSearchResults; }
        }

        public ObservableCollection<IMessage> Mentions
        {
            get { return _mentions; }
        }

        public ObservableCollection<IMessage> AllReceivedMessages
        {
            get 
            {
                return _allReceivedMessages; 
            }
        }

        public ObservableCollection<IMessage> FriendsStatus
        {
            get
            {
                return _friendsStatus;                
            }
        }

        public ObservableCollection<IMessage> DirectMessages
        {
            get { return _directMessages; }
        }

        public Trends Trends
        {
            get { return _trends; }
        }

        public Twitter()
        {
            _friendsStatus = new Tweets();
            _allReceivedMessages = new Tweets();
            ((IBreadcrumbExplorerEntity)_allReceivedMessages).Name = "Home";
            _directMessages = new Tweets();
            ((IBreadcrumbExplorerEntity)_directMessages).Name = "Home";
            _mentions = new Tweets();
            ((IBreadcrumbExplorerEntity)_mentions).Name = "Home";
            _lastSearchResults = new Tweets();
            ((IBreadcrumbExplorerEntity)_lastSearchResults).Name = "Home";
            _trends = new Trends();
        }        

        public void SyncWithTwitterProvider()
        {
            GlobalController.Instances.ITwitterProvider.DirectMessagesUpdated += new DirectMessagesUpdatedHandler(ITwitterProvider_DirectMessagesUpdated);
            GlobalController.Instances.ITwitterProvider.StatusUpdated += new StatusUpdatedHandler(ITwitterProvider_StatusUpdated);
            GlobalController.Instances.ITwitterProvider.MentionsUpdated += new MentionsUpdatedHandler(ITwitterProvider_MentionsUpdated);
            GlobalController.Instances.ITwitterProvider.IMessagesUpdateError += new IMessagesUpdateErrorHandler(ITwitterProvider_IMessagesUpdateError);
            GlobalController.Instances.ITwitterProvider.SearchCompleted += new SearchCompletedHandler(ITwitterProvider_SearchCompleted);
            GlobalController.Instances.ITwitterProvider.ConnectedUserInfoUpdated += new ConnectedUserInfoUpdatedHandler(ITwitterProvider_ConnectedUserInfoUpdated);
            GlobalController.Instances.ITwitterProvider.TrendsUpdated += new TrendsUpdatedHandler(ITwitterProvider_TrendsUpdated);
            GlobalController.Instances.ITwitterProvider.RefreshStatus(new TimeSpan(0, 1, 30));
            GlobalController.Instances.ITwitterProvider.RefreshDirectMessages(new TimeSpan(0, 5, 0));
            GlobalController.Instances.ITwitterProvider.RefreshMentions(new TimeSpan(0, 6, 0));
            GlobalController.Instances.ITwitterProvider.RefreshUserInfo(new TimeSpan(0, 7, 0));
            GlobalController.Instances.ITwitterProvider.RefreshTrends(new TimeSpan(0, 10, 0));
        }

        /// <summary>
        /// Clear all messages
        /// </summary>
        public void Reset()
        {
            _friendsStatus.Clear();
            _allReceivedMessages.Clear();
            _directMessages.Clear();
            _mentions.Clear();
            _lastSearchResults.Clear();
            _trends.CurrentTrends.Clear();
        }

        void ITwitterProvider_ConnectedUserInfoUpdated(User user)
        {
            _connectedUserInfo = user;
            RaisePropertyChanged("ConnectedUserInfo");
        }

        void ITwitterProvider_SearchCompleted(List<IMessage> entries)
        {
            _lastSearchResults = new Tweets(entries);
            ((IBreadcrumbExplorerEntity)_lastSearchResults).Name = "Home";
            RaisePropertyChanged("LastSearchResults");
        }

        void ITwitterProvider_TrendsUpdated(Trends trends)
        {
            _trends = trends;
            RaisePropertyChanged("Trends");
        }

        void ITwitterProvider_MentionsUpdated(List<Status> updatedstatus)
        {
            List<IMessage> messages = new List<IMessage>();
            foreach (Status status in updatedstatus)
                messages.Add(status);
            UpdateModel(messages);
        }

        void ITwitterProvider_StatusUpdated(List<Status> updatedstatus)
        {
            List<IMessage> messages = new List<IMessage>();
            foreach (Status status in updatedstatus)
                messages.Add(status);
            UpdateModel(messages);
        }

        void ITwitterProvider_DirectMessagesUpdated(List<DirectMessage> updatedDirectMessages)
        {
            List<IMessage> messages = new List<IMessage>();
            foreach (DirectMessage status in updatedDirectMessages)
                messages.Add(status);
            UpdateModel(messages);
        }        

        void UpdateModel(List<IMessage> updatedIMessages)
        {
            ObservableCollection<IMessage> newMessages = new ObservableCollection<IMessage>(updatedIMessages);
            List<IMessage> messagesToNotify = new List<IMessage>();
            bool _allReceivedMessagesChanged=false;
            bool _directMessagesChanged=false;
            bool _mentionsChanged=false;

            foreach (IMessage message in newMessages)
            {
                if (!_allReceivedMessages.Contains(message, new IMessagesAreEqualComparer()))
                {
                    _allReceivedMessages.Add(message);
                    _allReceivedMessagesChanged = true;
                }

                if (message is DirectMessage)
                {
                    if (!_directMessages.Contains(message, new IMessagesAreEqualComparer()))
                    {
                        _directMessages.Add(message);
                        messagesToNotify.Add(message);
                        _directMessagesChanged = true;
                    }
                }
                if (message is Status && ((Status)message).IsMention)
                {
                    if (!_mentions.Contains(message, new IMessagesAreEqualComparer()))
                    {
                        _mentions.Add(message);
                        messagesToNotify.Add(message);
                        _mentionsChanged = true;
                    }
                }
            }

            if (messagesToNotify.Count > 0 && messagesToNotify.Count < 6)
                GlobalController.Notify(messagesToNotify);


            if (_allReceivedMessagesChanged)
            {
                ListCollectionView allMessagesListViewCollection = (ListCollectionView)(CollectionViewSource.GetDefaultView(_allReceivedMessages));
                allMessagesListViewCollection.CustomSort = new IMessageSortingOnDate();
                RaisePropertyChanged("AllReceivedMessages");
            }

            if (_directMessagesChanged)
            {
                ListCollectionView directMessagesListViewCollection = (ListCollectionView)(CollectionViewSource.GetDefaultView(_directMessages));
                directMessagesListViewCollection.CustomSort = new IMessageSortingOnDate();
                RaisePropertyChanged("DirectMessages");
            }

            if (_mentionsChanged)
            {
                ListCollectionView mentionsListViewCollection = (ListCollectionView)(CollectionViewSource.GetDefaultView(_mentions));
                mentionsListViewCollection.CustomSort = new IMessageSortingOnDate();
                RaisePropertyChanged("Mentions");
            }      
        }

        void ITwitterProvider_IMessagesUpdateError(Exception exception)
        {
            ExceptionsManager.LogException("myTwitter", exception, false);            
        }        

        private void RaisePropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }

        #region INotifyPropertyChanged Members

        public event PropertyChangedEventHandler PropertyChanged;

        #endregion
    }
}
